package com.qf.ticket2301.controller;

import com.qf.ticket2301.R.R;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;

/**
 * @Author UNIQ7xi
 * @Date 2023/6/27 20:59
 * @Version v1.8
 **/
@RestController
@RequestMapping("/vote")
public class VoteController {
    private static final String REDIS_HOST = "localhost";
    private static final int REDIS_PORT = 3306;
    private static final String REDIS_KEY_PREFIX = "votes:";

    private static final String MQ_HOST = "localhost";
    private static final int MQ_PORT = 5672;
    private static final String MQ_USERNAME = "guest";
    private static final String MQ_PASSWORD = "guest";
    private static final String EXCHANGE_NAME = "vote-exchange";
    private static final String QUEUE_NAME = "vote-queue";
    private static final String ROUTING_KEY = "vote.#";

    private Jedis jedis;
    private Channel channel;

    public VoteController() {
        // 初始化 Redis 连接
        jedis = new Jedis(REDIS_HOST, REDIS_PORT);
        jedis.connect();

        // 初始化 RabbitMQ 连接
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(MQ_HOST);
        factory.setPort(MQ_PORT);
        factory.setUsername(MQ_USERNAME);
        factory.setPassword(MQ_PASSWORD);

        try {
            Connection connection = factory.newConnection();
            channel = connection.createChannel();

            // 声明交换机和队列
            channel.exchangeDeclare(EXCHANGE_NAME, "topic");
            channel.queueDeclare(QUEUE_NAME, true, false, false, null);
            channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/pick")
    public R vote(String phoneNumber, String candidateName) {
        // 检查是否满足每分钟只能投一票的要求
        if (!canVote(phoneNumber)) {
            return new R("每分钟只能投一票", 0);
        }

        // 给候选人投票
        long totalVotes = jedis.hincrBy(REDIS_KEY_PREFIX + candidateName, "totalnum", 1);

        // 发送投票信息到 RabbitMQ
        String json = String.format("{\"phone\":\"%s\",\"candidate\":\"%s\",\"timestamp\":%d}",
                phoneNumber, candidateName, System.currentTimeMillis());
        try {
            channel.basicPublish(EXCHANGE_NAME, "vote.new", null, json.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new R("OK", totalVotes);
    }

    private boolean canVote(String phoneNumber) {
        String key = REDIS_KEY_PREFIX + "user:" + phoneNumber;
        if (jedis.exists(key)) {
            // 已经投过票
            return false;
        } else {
            // 设置有效期为一分钟
            jedis.setex(key, 60, "");
            return true;
        }
    }

    public static void main(String[] args) {
        VoteController voteSystem = new VoteController();
        R result = voteSystem.vote("13812345678", "张靓颖");
        System.out.println(result.getMsg());
        System.out.println(result.getData().getTotalnum());
    }
}
